/**
 * 
 */
package edu.umd.clip.lm.model.data;

import edu.umd.clip.lm.factors.*;
import edu.umd.clip.lm.util.*;

import java.io.*;
import java.nio.ByteBuffer;
import java.util.regex.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class TupleCountPair implements Serializable, Externalizable {
	static final long serialVersionUID = 1L;
	public long tuple;
	public int count;
	private static final Pattern split_re = Pattern.compile("-");
	
	public TupleCountPair(long tuple, int count) {
		this.tuple = tuple;
		this.count = count;
	}

	public TupleCountPair(String valueString) {
		String parts[] = split_re.split(valueString);
		assert(parts.length == 2);
		tuple = FactorTuple.factorTuple(parts[0]);
		count = Integer.parseInt(parts[1]);
	}
	
	public TupleCountPair(ObjectInput in) throws IOException, ClassNotFoundException {
		read(in);
	}
	
	public TupleCountPair(DataInput in) throws IOException {
		read(in);
	}
	
	public TupleCountPair(ByteBuffer buffer) {
		read(buffer);
	}
	
	public static TupleCountPair[] fromMap(Long2IntMap map) {
		TupleCountPair futures[] = new TupleCountPair[map.size()];
		int idx = 0;
		for(Long2IntMap.Iterator i = map.iterator(); i.hasNext();) {
			Long2IntMap.Entry entry = i.next();
			futures[idx++] = new TupleCountPair(entry.getKey(), entry.getValue());
		}
		return futures;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 * NOTE: the counts are ignored
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj.getClass() != TupleCountPair.class) return false;
		TupleCountPair other = (TupleCountPair) obj; 
		return tuple == other.tuple;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return FactorTuple.hashCode(tuple);
	}
	
	public String toValueString() {
		return FactorTuple.toValueString(tuple) + "-" + Long.toString(count);
	}

	@Override
	public String toString() {
		return FactorTuple.toString(tuple) + "-" + Long.toString(count);
	}

	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		read(in);
	}
	
	public void read(DataInput in) throws IOException {
		tuple = in.readLong();
		count = in.readInt();
	}

	public void read(ByteBuffer buffer) {
		tuple = buffer.getLong();
		count = buffer.getInt();
	}
	
	public void writeExternal(ObjectOutput out) throws IOException {
		write(out);
	}
	public void write(DataOutput out) throws IOException {
		out.writeLong(tuple);
		out.writeInt(count);
	}
	
	public void write(GrowingOutputBuffer buffer) {
		buffer.putLong(tuple);
		buffer.putInt(count);
	}
}
